package cn.guo.app.lan.msg.activity;

import android.app.Activity;
import android.content.Context;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;

import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Enumeration;

import butterknife.ButterKnife;
import butterknife.InjectView;
import butterknife.OnClick;
import cn.guo.app.lan.msg.R;
import cn.guo.app.lan.msg.utils.G;

/**
 * Created by guo on 2015/10/29.
 */
public class MainActivity extends Activity {

    //开启监听的端口,用于接收消息
    private static final int LOCAL_PORT = 9999;
    private static final String CHARSET = "UTF-8";
    //组播地址
    private static final String MULTICAST_HOST = "225.0.0.1";

    private static final String KEY_IP = "IP";
    private static final String KEY_MSG = "MSG";
    private static final String KEY_SEND = "SEND";

    @InjectView(R.id.scroll_box)
    ScrollView scrollBox;

    @InjectView(R.id.ipt_content)
    EditText content;

    @InjectView(R.id.item_box)
    LinearLayout itemBox;

    private Context context;
    private Handler handler;
    private WifiManager.MulticastLock lock;
    private MsgReceiveThread receiveThread;

    private String localIp;

//    private MsgService.MsgBinder binder;
//
//    private ServiceConnection connection;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.inject(this);
        init();
    }

    @Override
    protected void onDestroy() {
        G.w("-MainActivity:onDestroy-");
        super.onDestroy();
        receiveThread.kill();
        //unbindService(connection);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main,menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case R.id.action_clear:
                clearItemBox();
                break;

            default:break;
        }
        return  true;
    }

    private void clearItemBox() {
        itemBox.removeAllViews();
    }

    private void init() {
        context = this;
        initWifiMulticastLock();
        startMsgReceiveThread();
        initHandler();
        initWifiLocalIp();
        //startMsgService();
    }

    private void initWifiMulticastLock() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                WifiManager manager = (WifiManager) context.getSystemService(WIFI_SERVICE);
                lock = manager.createMulticastLock(G.TAG);
            }
        });

    }

    private void initWifiLocalIp() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                WifiManager wifiManager = (WifiManager) context.getSystemService(WIFI_SERVICE);
                if (!wifiManager.isWifiEnabled()) {
                    G.t(context, "请先打开WIFI，获取局域网地址");
                } else {
                    WifiInfo info = wifiManager.getConnectionInfo();
                    int ipInt = info.getIpAddress();
                    String ip = convertIp(ipInt);
                    G.w("["+ipInt+"]>>["+ip+"]");
                    localIp = ip;
                }
            }

            private String convertIp(int ipAddress) {
                return (ipAddress & 0xff) + "." + (ipAddress >> 8 & 0xff) + "." + (ipAddress >> 16 & 0xff) + "." + (ipAddress >> 24 & 0xff);

            }
        });


    }

    private void initLocalIp() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                try {
                    Enumeration<NetworkInterface> nis = NetworkInterface.getNetworkInterfaces();
                    while (nis.hasMoreElements()) {
                        NetworkInterface ifa = nis.nextElement();
                        Enumeration<InetAddress> ias = ifa.getInetAddresses();
                        while (ias.hasMoreElements()) {
                            InetAddress ia = ias.nextElement();
                            G.w("IP:" + ia.getHostAddress());
                            if (!ia.isLoopbackAddress()) {
                                localIp = ia.getHostAddress();
                            }
                        }
                    }
                } catch (SocketException e) {
                    e.printStackTrace();
                }
            }
        });

    }


    private void initHandler() {
        handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                Bundle bundle = msg.getData();
                String ip = bundle.getString(KEY_IP);
                String content = bundle.getString(KEY_MSG);
                boolean send = bundle.getBoolean(KEY_SEND);
                G.w("[" + ip + ":" + send + ":" + content + "]");
                appendMsg(ip, content, send);
            }
        };
    }

    private void startMsgReceiveThread() {
        receiveThread = new MsgReceiveThread();
        receiveThread.start();
    }

    @OnClick({R.id.btn_send})
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_send:
                sendMsg();
                break;
            default:
                break;
        }
    }

    private void appendMsg(String ip, String msg, boolean send) {
        View view;
        if (send) {
            view = getLayoutInflater().inflate(R.layout.item_send, null);
        } else {
            view = getLayoutInflater().inflate(R.layout.item_recive, null);
        }

        TextView label = (TextView) view.findViewById(R.id.item_label);
        TextView content = (TextView) view.findViewById(R.id.item_content);
        label.setText(ip);
        content.setText(msg);
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        lp.setMargins(0, 0, 0, getResources().getDimensionPixelSize(R.dimen.margin));
        view.setLayoutParams(lp);
        itemBox.addView(view);
        handler.post(new Runnable() {
            @Override
            public void run() {
                scrollBox.fullScroll(View.FOCUS_DOWN);
            }
        });
    }


    private void sendMsg() {
        String msg = content.getText().toString().trim();
        sendMsg(msg);
    }

    /**
     * 发送消息
     *
     * @param message
     */
    public void sendMsg(final String message) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                MulticastSocket sendSocket = null;
                try {
                    sendSocket = new MulticastSocket();
                    InetAddress group = InetAddress.getByName(MULTICAST_HOST);
                    sendSocket.joinGroup(group);

                    String _msg = URLEncoder.encode(message, CHARSET);
                    DatagramPacket dp = new DatagramPacket(_msg.getBytes(), _msg.length(), group, LOCAL_PORT);

                    sendSocket.send(dp);
                    sendSocket.close();

                    Bundle bundle = new Bundle();
                    bundle.putString(KEY_IP, localIp);
                    bundle.putString(KEY_MSG, message);
                    bundle.putBoolean(KEY_SEND, true);
                    Message message = new Message();
                    message.setData(bundle);
                    handler.sendMessage(message);
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if (sendSocket != null) {
                        sendSocket.close();
                    }
                }
            }
        }).start();

    }


    /**
     * ************************内部类************************************
     */

    private class MsgReceiveThread extends Thread {
        private boolean flag = true;

        public void kill() {
            flag = false;
        }


        @Override
        public void run() {
            MulticastSocket ms = null;
            DatagramPacket dp;
            try {
                //绑定端口的
                ms = new MulticastSocket(LOCAL_PORT);
                G.w("监听多播端口打开：" + LOCAL_PORT);
                byte[] buf = new byte[1024];//存储发来的消息
                dp = new DatagramPacket(buf, buf.length);
                //加入多播地址
                InetAddress group = InetAddress.getByName(MULTICAST_HOST);
                ms.joinGroup(group);

                while (flag) {
                    lock.acquire();
                    ms.receive(dp);
                    byte[] data = dp.getData();
                    if (data.length > 0) {
                        String msg = new String(data, 0, dp.getLength());
                        final String ip = dp.getAddress().getHostAddress();
                        G.w("收到IP：" + ip);
                        if (msg.length() > 0 && !ip.equalsIgnoreCase(localIp) ) {
                            msg = URLDecoder.decode(msg, CHARSET);
                            G.w("收到广播消息：" + msg);
                            Bundle bundle = new Bundle();
                            bundle.putString(KEY_IP, ip);
                            bundle.putString(KEY_MSG, msg);
                            Message message = new Message();
                            message.setData(bundle);

                            handler.sendMessage(message);
                        }
                    }
                    lock.release();
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (ms != null) {
                    ms.close();
                }
            }
        }
    }
}
